<template>
  <div :class="$style.page">
    <!-- 表格 -->
    <div :class="$style.table">
      <el-table ref="tableRef" border height="100%" :data="tableData" v-bind="attrs">
        <z-table-column
          :list="columns"
          :i18n="i18n"
          :i18n-prefix="columnsI18nPrefix"
        ></z-table-column>
      </el-table>
    </div>

    <!-- 分页 -->
    <t-pagination
      :class="$style.pagination"
      v-model:page-size="paginationOpts.pageSize"
      v-model:current-page="paginationOpts.page"
      :total="paginationOpts.total"
      background
      :layout="pagination.layout"
      :page-sizes="pagination.pageSizes"
      @size-change="onPaginationSizeChange"
      @current-change="onPaginationCurrentChange"
    ></t-pagination>

    <!-- 弹窗 -->
    <t-dialog-form
      v-model="dialogOpts.show"
      :forms="editForms"
      :loading="dialogOpts.loading"
      :title="dialogTitle"
      :show-reset-button="showResetButton"
      :show-sustain-button="dialogOpts.type != 1 && showSustainButton"
      :close-on-click-modal="dialogOpts.type == 1"
      :i18n="i18n"
      :forms-i18n-prefix="formsI18nPrefix"
      :forms-item-width="formsItemWidth"
      :forms-label-width="formsLabelWidth"
      :forms-inline="formsInline"
      :width="dialogWidth"
      @save="onSave"
      @sustain="onSave"
    ></t-dialog-form>
  </div>
</template>

<script lang="ts" setup>
import tDialogForm from '../dialog-form/index.vue'
import tPagination from '../pagination/index.vue'
import { getDialogOpts, getPaginationOpts } from './data'
import * as MD from './methods'
import { Message } from '@/utils/element'
import { useUserStore } from '@/stores'
import { useI18n } from 'vue-i18n'

const userStore = useUserStore()

const attrs = useAttrs()

const props = withDefaults(defineProps<import('./type').Props>(), {
  props: () => ({
    pageNo: 'pageNo',
    pageSize: 'pageSize'
  }),
  dialogWidth: '3.5rem',
  pagination: () => ({}),
  filters: () => ({})
})

const { t } = useI18n()
const $t = (text: string = '') => {
  return t(`component.ztable.${text}`)
}

// 弹窗配置
const dialogOpts = reactive(getDialogOpts())

// 分页配置
const paginationOpts = reactive(getPaginationOpts())

// 编辑表单
const editForms = ref<ZForms>({})

// 标题
const dialogTitle = computed(() => {
  return dialogOpts.type == 0 ? $t('add') : $t('edit')
})

// 表格
const tableRef = useTemplateRef('tableRef')

// 表格展示数据
const tableData = ref<AnyObject[]>([])

// 编辑行
const editRow = ref<AnyObject>({})

// 查询
const query = () => {
  const _props = props.props
  const params = {
    projectId: userStore.projectId,
    ...props.filters
  } as Parameters<typeof props.queryFn>[0]

  if (!props?.notPage) {
    params[_props.pageNo || 'pageNo'] = paginationOpts.page
    params[_props.pageSize || 'pageSize'] = paginationOpts.pageSize
  }

  props.queryFn(params).then(res => {
    const isArr = res instanceof Array
    paginationOpts.total = isArr ? res.length : res.total
    tableData.value = isArr ? res : res.list || res.data
  })
}

// 添加
const add = () => {
  convertForms()
  // 新增
  dialogOpts.type = 0
  dialogOpts.loading = false
  dialogOpts.show = true
}

// 编辑
const edit = (scope: AnyObject) => {
  editRow.value = scope.row
  dialogOpts.type = 1
  dialogOpts.loading = false
  convertForms(scope.row)
  dialogOpts.show = true
}

// 编辑状态
const isEdit = computed(() => dialogOpts.type == 1)

// 删除-单
const del = (id: any) => {
  if (typeof props.delFn !== 'function') throw Error('删除方法 delFn 未传入')

  ElMessageBox.confirm($t('confirm.delete'), $t('confirm.delete_title'), { type: 'warning' }).then(
    () => {
      if (typeof props.delFn === 'function') {
        props.delFn(id).then(() => {
          Message($t('msg.delete_success'))
          query()
        })
      }
    }
  )
}

// 删除-多
const dels = () => {
  const list = tableRef.value?.getSelectionRows() || []
  if (list.length == 0) {
    return Message($t('msg.no_select'), 'error')
  }

  if (typeof props.delsFn !== 'function' && typeof props.delFn !== 'function')
    throw Error('删除方法 deslFn 或 delFn 未传入')

  const fn = props.delsFn || props.delFn
  ElMessageBox.confirm($t('confirm.delete_multiple'), $t('confirm.delete_title'), {
    type: 'warning'
  }).then(() => {
    if (fn)
      MD.checkFunction(
        props.beforeDelete,
        res => {
          console.log(res)
          fn(res).then(() => {
            Message($t('msg.delete_success'))
            query()
          })
        },
        list
      )
  })
}

// 保存
const onSave = (model: AnyObject) => {
  const params = {
    ...model,
    id: '',
    projectId: userStore.projectId
  }
  const _isEdit = isEdit.value
  if (dialogOpts.type == 1) {
    params.id = editRow.value.id
  }

  MD.checkFunction(
    props.beforeSubmit,
    result => {
      let opts = {}
      if (result instanceof Array) {
        opts = result
      } else {
        Object.assign(params, opts, result || {})
      }
      const fn = _isEdit ? props.editFn : props.addFn
      dialogOpts.loading = true

      if (!fn)
        throw Error(`${_isEdit ? '编辑' : '添加'}方法 ${_isEdit ? 'editFn' : 'addFn'} 未传入`)
      fn(params)
        .then(() => {
          dialogOpts.loading = false
          Message(dialogTitle.value + $t('msg.success'))
          query()
        })
        .catch(() => {
          dialogOpts.loading = false
        })
    },
    params,
    _isEdit ? editRow.value : void 0
  )
}

// 分页切换
const onPaginationSizeChange = (_size: number) => {
  query()
}

// 当前页切换
const onPaginationCurrentChange = (_current: number) => {
  query()
}

const initPage = () => {}

// 转换表单
const convertForms = (model?: AnyObject) => {
  if (!props.forms) return
  const forms = MD.getNewForms(props.forms, model)
  editForms.value = forms
}

// 深度监听变化
watch(
  () => props.forms,
  () => {
    if (dialogOpts.show) {
      const _isEdit = isEdit.value
      convertForms(_isEdit ? editRow.value : void 0)
    }
  },
  {
    deep: true
  }
)

onMounted(initPage)

defineExpose({
  add,
  edit,
  del,
  dels,
  query
})
</script>

<style lang="scss" module>
@use './style.scss';
</style>
